package com.xqboss.apps.service.sys;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xqboss.apps.domain.sys.SysAnnouncementCategory;
import com.xqboss.apps.domain.sys.SysAnnouncementMsg;
import com.xqboss.apps.dto.system.SysAnnouncementCategoryDto;
import com.xqboss.apps.mapper.sys.SysAnnouncementCategoryMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xqboss.apps.vo.sys.SysAnnouncementCategoryVo;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.common.utils.AsyncHandlerUtil;
import com.xqboss.common.utils.StringUtils;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 公告分类表 服务实现类
 * </p>
 *
 * @author 木鱼
 * @since 2024-03-18
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class SysAnnouncementCategoryService extends ServiceImpl<SysAnnouncementCategoryMapper, SysAnnouncementCategory> {

    private final  SysAnnouncementMsgService sysAnnouncementMsgService;

    public IPage<SysAnnouncementCategory> selectBasicList(SysAnnouncementCategoryDto<SysAnnouncementCategory> dto) {
        Page<SysAnnouncementCategory> page = this.page(
                dto.newPage(),
                Wrappers.lambdaQuery(SysAnnouncementCategory.class)
                        .eq(StringUtils.isNotEmpty(dto.getCategoryName()), SysAnnouncementCategory::getCategoryName, dto.getCategoryName())
                        .eq(ObjUtil.isNotEmpty(dto.getIsDisplay()), SysAnnouncementCategory::getIsDisplay, dto.getIsDisplay())
        );
        if (ObjUtil.isNotEmpty(page) && CollUtil.isNotEmpty(page.getRecords())) {
            for (SysAnnouncementCategory record : page.getRecords()) {
                record.setBindCount(sysAnnouncementMsgService.lambdaQuery().eq(SysAnnouncementMsg::getCategoryId, record.getId()).count());
            }
        }
        return page;
    }


    @Transactional
    public void saveOrUpdateBasic(SysAnnouncementCategory category) {
        this.lambdaQuery()
                .eq(SysAnnouncementCategory::getCategoryName,category.getCategoryName())
                .ne(category.getId()!=null,SysAnnouncementCategory::getId,category.getId()).oneOpt().ifPresent(e->{
                throw new RuntimeException("分类名称已存在~");
        });
        Assert.isTrue(this.saveOrUpdate(category),()->new ServiceException(String.format("公告分类%s失败~", category.getId() == null ? "新增" : "编辑")));
    }


    @Transactional
    public void removeBasic(Long id) {
        Assert.notNull(this.getById(id),()->new ServiceException("未查询到该公告分类信息~"));
        Assert.isTrue(this.removeById(id),()->new ServiceException("删除失败~"));
    }


    @Transactional
    public void association(Long categoryId,List<Long> ids) {
        Assert.notNull(this.getById(categoryId),()->new ServiceException("未查询到对应公告分类~"));
        List<SysAnnouncementMsg> msgs = this.sysAnnouncementMsgService.lambdaQuery().in(SysAnnouncementMsg::getId, ids).list();
        Assert.isTrue(CollUtil.isNotEmpty(msgs),()->new ServiceException("未查询到对应公告信息~"));
        msgs.forEach(e->e.setCategoryId(categoryId));
        Assert.isTrue(this.sysAnnouncementMsgService.updateBatchById(msgs),()->new ServiceException("关联失败~"));;
    }


    public List<SysAnnouncementCategory> data(){
        return  this.lambdaQuery()
                .select(SysAnnouncementCategory::getId, SysAnnouncementCategory::getCategoryName)
                .eq(SysAnnouncementCategory::getIsDisplay, true)
                .orderByAsc(SysAnnouncementCategory::getSort)
                .list();
    }


    /***
     * app公告分类数据
     *
     * @return list
     */
    public List<SysAnnouncementCategoryVo> categoryData(Long userId) {
        List<SysAnnouncementCategoryVo> vos = BeanUtil.copyToList(data(), SysAnnouncementCategoryVo.class);
        if (CollUtil.isNotEmpty(vos)) {
            List<Runnable> runnables = new ArrayList<>(vos.size());
            for (SysAnnouncementCategoryVo vo : vos) {
                runnables.add(()->vo.setIsRead(sysAnnouncementMsgService.getBaseMapper().isRead(vo.getId(), userId)));
            }
            AsyncHandlerUtil.runAllJoin(runnables);
        }
        return vos;
    }
}